#include "unp.h"

int Socket(int domain, int type, int protocol)
{
    int n;

    if ((n = socket(domain, type, protocol)) < 0) {
        err_sys("socket error");
    }
    return n;
}

void Bind(int fd, struct sockaddr *sa, socklen_t salen)
{
    if (bind(fd, sa, salen) < 0) {
        err_sys("bind error");
    }
}

void Listen(int fd, int backlog)
{
    if (listen(fd, backlog) < 0) {
        err_sys("listen error");
    }
}

int Accept(int fd, struct sockaddr* sa, socklen_t* salenptr)
{
    int n;

again:
    if ( (n=accept(fd, sa, salenptr)) < 0) {
        if (errno==EPROTO || errno==ECONNABORTED) {
            goto again;
        } else {
            err_sys("accept error");
        }
    }
    return n;
}

void Connect(int fd, struct sockaddr *sa, socklen_t salen)
{
    if (connect(fd, sa, salen) < 0) {
        err_sys("connect error");
    }
}

ssize_t Send(int fd, void *buf, size_t buflen, int flags)
{
    int n;

    if ( (n=send(fd, buf, buflen, flags)) < 0) {
        err_sys("send error");
    }
    return n;
}

ssize_t Recv(int fd, void *buf, size_t buflen, int flags)
{
    int n;

    if ( (n=recv(fd, buf, buflen, flags)) < 0) {
        err_sys("recv error");
    }
    return n;
}

void Close(int fd)
{
    if (close(fd) < 0) {
        err_sys("close error");
    }
}

void Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
    if (getpeername(fd, sa, salenptr) < 0) {
        err_sys("getpeername error");
    }
}

void Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
    if (getsockname(fd, sa, salenptr) < 0)
    {
        err_sys("getsockname error");
    }
}

ssize_t Recvfrom(int fd, void *buf, size_t len, int flags, 
                 struct sockaddr *addr, socklen_t *fromlen)
{
    ssize_t n;
    
    if ( (n=recvfrom(fd, buf, len, flags, addr, fromlen)) < 0) {
        err_sys("recvfrom error");
    }

    return n;
}

void Sendto(int fd, void *buf, size_t len, int flags,
            struct sockaddr *addr, socklen_t tolen)
{
    if (sendto(fd, buf, len, flags, addr, tolen) != (ssize_t)len) {
        err_sys("sendto error");
    }
}
        
